package nodes

import (
	"parse/src/token"
	"parse/src/utils"
)

// 所有的节点的父类，用来实现继承
type BaseNode struct {
	PosStart *token.Position
	PosEnd   *token.Position
}

/**数字节点**/
type NumberNode struct {
	Tok *token.Token // token
	BaseNode
}

// 实例化数字的节点x
func NewNumberNode(self *NumberNode) *NumberNode {
	temp := self
	temp.PosStart = self.Tok.PosStart
	temp.PosEnd = self.Tok.PosEnd
	return temp
}

/**字符串节点**/
type StringNode struct {
	Tok *token.Token
	BaseNode
}

// 实例化字符串的节点
func NewStringNode(self *StringNode) *StringNode {
	temp := self
	temp.PosStart = self.Tok.PosStart
	temp.PosEnd = self.Tok.PosEnd
	return temp
}

/**list节点**/
type ListNode struct {
	ElementNodes []interface{} // 所有元素的节点
	BaseNode
}

// 实例化List的节点
func NewListNode(node *ListNode) *ListNode {
	return node
}

/**变量节点**/
type VarAccessNode struct {
	VarNameTok *token.Token // 变量名字token
	BaseNode
}

// 实例化变量的节点
func NewVarAccessNode(self *VarAccessNode) *VarAccessNode {
	temp := self
	temp.PosStart = self.VarNameTok.PosStart
	temp.PosEnd = self.VarNameTok.PosEnd
	return temp
}

/**变量分配节点**/
type VarAssignNode struct {
	VarNameTok   *token.Token // 变量的名字 token
	VarValueNode interface{}  // 变量的值 节点
	BaseNode
}

// 实例化变量分配的节点
func NewVarAssignNode(self *VarAssignNode) *VarAssignNode {
	temp := self
	temp.PosStart = self.VarNameTok.PosStart // 变量名字token的开始位置
	baseNode := utils.GetItemAttribute(self.VarValueNode, "BaseNode")
	temp.PosEnd = baseNode.(BaseNode).PosEnd // 变量值token的结束位置
	return temp
}

/**操作的 节点 比如 a = a + b 作为一个 op **/
type BinOpNode struct {
	LeftNode  interface{}  // 左节点 token
	OpTok     *token.Token // 操作 token
	RightNode interface{}  // 右节点 token

	BaseNode
}

// 实例化  操作 的节点
func NewBinOpNode(self *BinOpNode) *BinOpNode {
	temp := self
	baseNode := utils.GetItemAttribute(self.LeftNode, "BaseNode")
	temp.PosStart = baseNode.(BaseNode).PosStart // 变量名字token的开始位置
	temp.PosEnd = baseNode.(BaseNode).PosEnd     // 变量值token的结束位置
	return temp
}

/**一元表达式 操作的 节点 比如 a = a + b 作为一个 op **/
type UnaryOpNode struct {
	OpTok *token.Token // 操作 token
	Node  interface{}  // 右节点

	BaseNode
}

// 实例化  一元表达式 操作 的节点
func NewUnaryOpNode(self *UnaryOpNode) *UnaryOpNode {
	temp := self
	temp.PosStart = self.OpTok.PosStart
	baseNode := utils.GetItemAttribute(self.Node, "BaseNode")
	temp.PosEnd = baseNode.(BaseNode).PosEnd
	return temp
}

/** if 的节点 **/
type IfNode struct {
	Cases    []Case    // case token
	ElseCase *ElseCase // elseCase token

	BaseNode
}

/***********以下是 IF 条件的每个的条件的结构体*************/
type Case struct {
	Condition        interface{} // 条件，是个节点
	Expr             interface{} // 表达式，也是个节点
	ShouldReturnNull bool        // 是否返回null

	BaseNode
}
type ElseCase struct {
	Condition        interface{} // 条件，是个节点
	Expr             interface{} // 表达式，也是个节点
	ShouldReturnNull bool        // 是否是?

	BaseNode
}

// if a elseif b elseif c else
type AllCases struct {
	Cases    []Case    // case有很多个
	ElseCase *ElseCase // elseCase只有一个
}

// 实例化  If操作 的节点
func NewIfNode(self *IfNode) *IfNode {
	temp := self

	temp.PosStart = self.Cases[0].PosStart
	if self.ElseCase != nil {
		temp.PosEnd = self.ElseCase.PosEnd
	} else {
		temp.PosEnd = self.Cases[len(self.Cases)-1].PosEnd
	}
	return temp
}

/** for 的节点 for var1 0 100 2 { }**/
type ForNode struct {
	VarNameToken     *token.Token // 变量名字 token
	StartValueNode   interface{}  // 开始值 token
	EndValueNode     interface{}  // 结束值 token
	StepValueNode    interface{}  // 步 token
	BodyNode         interface{}  // 整体的内容节点 token
	ShouldReturnNull bool  // 是否返回null token

	*BaseNode
}

// 实例化  For 的节点
func NewForNode(self *ForNode) *ForNode {
	temp := self

	temp.BaseNode = &BaseNode{
		PosStart: self.VarNameToken.PosStart,
		PosEnd:   self.VarNameToken.PosEnd,
	}
	return temp
}

/** while 的节点 while { }**/
type WhileNode struct {
	ConditionNode    interface{} // 条件 token
	BodyNode         interface{} // 整体的内容节点 token
	ShouldReturnNull interface{} // 是否返回null token

	BaseNode
}

// 实例化  while 的节点
func NewWhileNode(self *WhileNode) *WhileNode {
	temp := self

	baseNode1 := utils.GetItemAttribute(self.ConditionNode, "BaseNode")
	temp.PosStart = baseNode1.(BaseNode).PosStart
	baseNode2 := utils.GetItemAttribute(self.BodyNode, "BaseNode")
	temp.PosEnd = baseNode2.(BaseNode).PosEnd

	return temp
}

/** 函数定义 的节点 func asasd { } 或者匿名函数，或者是{} 也能作为函数**/
type FuncDefNode struct {
	VarNameTok       *token.Token  // 函数名字 token
	ArgNameToks      []token.Token // 函数的参数 token
	BodyNode         interface{}   // 整体的内容节点 token
	ShouldAutoReturn bool          // 是否返回 bool

	BaseNode
}

// 实例化  函数定义 的节点 func asasd { } 或者匿名函数，或者是{} 也能作为函数
func NewFuncDefNode(self *FuncDefNode) *FuncDefNode {
	temp := self
	baseNode := utils.GetItemAttribute(self.BodyNode, "BaseNode")
	// 定义一个空的token
	if self.VarNameTok != nil { // 传递的变量名称 token不为空
		temp.PosStart = self.VarNameTok.PosStart
	} else if len(self.ArgNameToks) > 0 { // 参数数量大于0
		temp.PosStart = self.ArgNameToks[0].PosStart
	} else {
		temp.PosStart = baseNode.(BaseNode).PosStart
	}
	temp.PosEnd = baseNode.(BaseNode).PosEnd
	return temp
}

/** 调用 的节点 **/
type CallNode struct {
	NodeToCall interface{}   // 函数名字 token
	ArgNodes   []interface{} // 是否返回null token

	BaseNode
}

// 调用  的节点
func NewCallNode(self *CallNode) *CallNode {
	temp := self

	baseNode1 := utils.GetItemAttribute(self.NodeToCall, "BaseNode")
	temp.PosStart = baseNode1.(BaseNode).PosStart
	// 参数节点的长度大于0，表示结束必须是这个，否则是nodeToCall的结束位置
	if len(self.ArgNodes) > 0 {
		baseNode2 := utils.GetItemAttribute(self.ArgNodes[len(self.ArgNodes)-1], "BaseNode")
		temp.PosEnd = baseNode2.(BaseNode).PosEnd
	} else {
		temp.PosEnd = baseNode1.(BaseNode).PosEnd
	}
	return temp
}

/** 返回 的节点 里面包含了 返回的节点**/
type ReturnNode struct {
	NodeToReturn interface{}

	BaseNode
}

// 返回  的节点
func NewReturnNode(self *ReturnNode) *ReturnNode {
	return self
}

/** continue 的节点 **/
type ContinueNode struct {
	BaseNode
}

// 返回 continue  的节点
func NewContinueNode(self *ContinueNode) *ContinueNode {
	return self
}

/** break 的节点 **/
type BreakNode struct {
	BaseNode
}

// 返回 break  的节点
func NewBreakNode(self *BreakNode) *BreakNode {
	return self
}
